﻿
using System.Collections.Generic;
using System.Text; 
using UnityEditor;
using UnityEditor.IMGUI.Controls; 
using UnityEngine;
using XFABManager; 

namespace XFGameFramework.Localization
{ 

    public class LanguageInfoListTree : DragableTreeView<LanguageInfo>
    {
        private Dictionary<int, GUIContent> iconContents = new Dictionary<int, GUIContent>();
          
        private LanguageConfig languageConfig;

        private MultiLanguageConfigs multiLanguageConfigs;

        private Dictionary<int, GUIContent> contents = new Dictionary<int, GUIContent>();

        private GUIStyle labelStyle = null;

        private bool isContextClickItem;

        #region 重写方法

        internal static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
        {
            return new MultiColumnHeaderState(GetColumns());
        }
        private static MultiColumnHeaderState.Column[] GetColumns()
        {
            var retVal = new MultiColumnHeaderState.Column[] {
                new MultiColumnHeaderState.Column(),
                new MultiColumnHeaderState.Column(),
                new MultiColumnHeaderState.Column(),
                new MultiColumnHeaderState.Column(),
                //new MultiColumnHeaderState.Column(),
            };
            retVal[0].headerContent = new GUIContent("ID", "语言配置唯一标识");
            retVal[0].minWidth = 50;
            retVal[0].width = 50;
            retVal[0].maxWidth = 200;
            retVal[0].headerTextAlignment = TextAlignment.Left;
            retVal[0].canSort = false;
            retVal[0].autoResize = true;

            retVal[1].headerContent = new GUIContent("类型", "多语言配置类型");
            retVal[1].minWidth = 50;
            retVal[1].width = 50;
            retVal[1].maxWidth = 200;
            retVal[1].headerTextAlignment = TextAlignment.Left;
            retVal[1].canSort = false;
            retVal[1].autoResize = true;

            retVal[2].headerContent = new GUIContent("值", "内容");
            retVal[2].minWidth = 100;
            retVal[2].width = 465;
            retVal[2].maxWidth =1200;
            retVal[2].headerTextAlignment = TextAlignment.Left;
            retVal[2].canSort = false;
            retVal[2].autoResize = true;


            retVal[3].headerContent = new GUIContent("备注", "备注");
            retVal[3].minWidth = 50;
            retVal[3].width = 50;
            retVal[3].maxWidth = 300;
            retVal[3].headerTextAlignment = TextAlignment.Left;
            retVal[3].canSort = false;
            retVal[3].autoResize = true;

            //retVal[4].headerContent = new GUIContent("操作", "操作");
            //retVal[4].minWidth = 60;
            //retVal[4].width = 100;
            //retVal[4].maxWidth = 300;
            //retVal[4].headerTextAlignment = TextAlignment.Left;
            //retVal[4].canSort = false;
            //retVal[4].autoResize = true;

            return retVal;
        }
  
        protected override void RowGUI(RowGUIArgs args)
        {
            for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
                CellGUI(args.GetCellRect(i), args.item as LanguageInfoTreeViewItem, args.GetColumn(i), ref args);
        }

      
        protected override void ContextClicked()
        {
            base.ContextClicked();

            if (isContextClickItem)
            {
                isContextClickItem = false;
                return;
            }

            GenericMenu menu = new GenericMenu();
            ShowMenu(menu);
        }

        protected override void ContextClickedItem(int id)
        {
            base.ContextClickedItem(id);
              
            isContextClickItem = true;

            GenericMenu menu = new GenericMenu();

            menu.AddItem(new GUIContent("删除"),false, () => 
            {

                StringBuilder content = new StringBuilder();

                content.AppendLine("确定删除多语言配置:");

                foreach (var item in this.GetSelection()) 
                {
                    LanguageInfo info = languageConfig.GetLanguageInfo(item);
                    content.Append("id:").Append(item).Append("值:");

                    switch (info.type)
                    {
                        case MultiLanguageType.String:
                            content.Append(info.str);
                            break;
                        case MultiLanguageType.Image:
                            content.Append(info.image.projectName).Append("/").Append(info.image.imageName);
                            break;
                        case MultiLanguageType.NetworkImage:
                            content.Append(info.url);
                            break; 
                    }

                    content.AppendLine(); 
                }


                    if (EditorUtility.DisplayDialog("删除", content.ToString(), "确定", "取消")) { 

                    foreach (var item in this.GetSelection())
                    {
                        Delete(item);
                    } 
                    
                    Reload();
                }
            });

#if UNITY_6000_2_OR_NEWER
            TreeViewItem<int> treeViewItem = FindItem(id, rootItem);
#else
            TreeViewItem treeViewItem = FindItem(id, rootItem);
#endif

            menu.AddItem(new GUIContent("编辑"), false, () => 
            {
                EditLanguageInfoWindow editLanguageInfoWindow = EditorWindow.GetWindow<EditLanguageInfoWindow>();
                editLanguageInfoWindow.ShowLanguageInfo(multiLanguageConfigs, languageConfig, languageConfig.GetLanguageInfo(id), treeViewItem); 
            });

            ShowMenu(menu);
        }

        protected override void DoubleClickedItem(int id)
        {
            base.DoubleClickedItem(id);

            LanguageInfoTreeViewItem treeViewItem = FindItem(id, rootItem) as LanguageInfoTreeViewItem;

            if(treeViewItem != null)
                EditorWindow.GetWindow<EditLanguageInfoWindow>().ShowLanguageInfo(multiLanguageConfigs, languageConfig, treeViewItem.languageInfo, treeViewItem);
        }

        protected override void RefreshDatas()
        {
            base.RefreshDatas();

            if(languageConfig)
                languageConfig.ClearCache();
        }

#endregion


        #region 方法
#if UNITY_6000_2_OR_NEWER
        public LanguageInfoListTree(TreeViewState<int> state, MultiColumnHeaderState mchs,LanguageConfig languageConfig,MultiLanguageConfigs multiLanguageConfigs) : base(languageConfig, languageConfig.languagesInfo,state, new MultiColumnHeader(mchs))
#else
        public LanguageInfoListTree(TreeViewState state, MultiColumnHeaderState mchs,LanguageConfig languageConfig,MultiLanguageConfigs multiLanguageConfigs) : base(languageConfig, languageConfig.languagesInfo,state, new MultiColumnHeader(mchs))

#endif

        {
            showBorder = true;
            showAlternatingRowBackgrounds = true; 
            rowHeight = 20; 

            this.languageConfig = languageConfig;
            this.multiLanguageConfigs = multiLanguageConfigs; 
        }

        private void CellGUI(Rect cellRect, LanguageInfoTreeViewItem item, int column, ref RowGUIArgs args)
        {

            if (labelStyle == null) 
            {
                labelStyle = new GUIStyle(GUI.skin.label);
                labelStyle.richText = true;
            }

            switch (column)
            {
                case 0: 
                    EditorGUI.LabelField(cellRect, item.languageInfo.id.ToString() );
                    break;
                case 1:
                    EditorGUI.LabelField(cellRect, item.languageInfo.type.ToString());
                    break;

                case 2:

                    if (!contents.ContainsKey(item.languageInfo.id)) 
                        contents.Add(item.languageInfo.id, new GUIContent());
                    

                    switch (item.languageInfo.type)
                    {
                        case MultiLanguageType.String:
                              
                            contents[item.languageInfo.id].text = GetStr(item.languageInfo,true);
                            contents[item.languageInfo.id].tooltip = GetStr(item.languageInfo,false);

                            EditorGUI.LabelField(cellRect, contents[item.languageInfo.id], labelStyle); 
                            break;
                        case MultiLanguageType.Image:

                            cellRect.width -= 20;

                            string projectName = item.languageInfo.image.projectName;
                            string imageName = item.languageInfo.image.imageName;

                            string message = string.Format("{0}/{1}", string.IsNullOrEmpty(projectName) ? "空" : projectName, string.IsNullOrEmpty(imageName) ? "空" : imageName);

                            EditorGUI.LabelField(cellRect, message);

                            if (!iconContents.ContainsKey(item.languageInfo.id))
                            {
                                iconContents.Add(item.languageInfo.id, new GUIContent(EditorGUIUtility.IconContent("BuildSettings.Broadcom")));

                                Texture texture = LanguageConfigsInspector.GetImage(item.languageInfo.image.projectName, item.languageInfo.image.imageName);

                                if (texture != null)
                                    iconContents[item.languageInfo.id].image = texture;
                                else
                                    iconContents[item.languageInfo.id].tooltip = string.Format("图片{0}/{1}加载失败,请检查名称是否正确，或是否添加到资源模块?", item.languageInfo.image.projectName, item.languageInfo.image.imageName);
                            }

                            cellRect.x += cellRect.width;
                            cellRect.width = 20;
                            if (GUI.Button(cellRect, iconContents[item.languageInfo.id]))
                            {
                                ImageWindow window = EditorWindow.GetWindow<ImageWindow>();
                                window.SetTarget(iconContents[item.languageInfo.id].image);
                                window.Show();
                            }

                            break;
                        case MultiLanguageType.NetworkImage:
                            EditorGUI.LabelField(cellRect, string.IsNullOrEmpty( item.languageInfo.url) ? "空" : item.languageInfo.url);
                            break;
                    }

                    break;

                case 3:

                    // 备注

                    if (!contents.ContainsKey(item.languageInfo.id))
                    {
                        contents.Add(item.languageInfo.id, new GUIContent());
                    }

                    contents[item.languageInfo.id].text = item.languageInfo.notes;
                    contents[item.languageInfo.id].tooltip = item.languageInfo.notes;
                     
                    EditorGUI.LabelField(cellRect, contents[item.languageInfo.id],labelStyle);

                    break;

                case 4:

                    cellRect.width = 60;

                    if (GUI.Button(cellRect, " 编辑")) 
                    {  
                        EditorWindow.GetWindow<EditLanguageInfoWindow>().ShowLanguageInfo(multiLanguageConfigs,languageConfig, item.languageInfo, item);
                    }
                    
                    break;

            }
        }

#if UNITY_6000_2_OR_NEWER

        protected override void OnBuildRoot(TreeViewItem<int> root, IList<LanguageInfo> datas)
#else
        protected override void OnBuildRoot(TreeViewItem root, IList<LanguageInfo> datas)
#endif

        {
            base.OnBuildRoot(root, datas);

            foreach (var item in datas)
            {
                LanguageInfoTreeViewItem languageInfoTreeViewItem = new LanguageInfoTreeViewItem(item);
                root.AddChild(languageInfoTreeViewItem);
            } 
        }
         
#endregion


        private string GetStr(LanguageInfo languageInfo,bool richText)
        { 

            if (LocalizationManager.Language == languageConfig.language)
            { 
                // 当前的选择的语言 与 选中的语言一致
                return string.IsNullOrEmpty(languageInfo.str) ? "空" : languageInfo.str;
            }
            else 
            {
                // 不一致

                LanguageConfig selectConfig = multiLanguageConfigs.GetLanguageConfigData(LocalizationManager.Language);
                if (selectConfig != null)
                {
                    string str = string.IsNullOrEmpty(languageInfo.str) ? "空" : languageInfo.str;

                    LanguageInfo selectInfo = selectConfig.GetLanguageInfo(languageInfo.id);

                    string str1 = string.IsNullOrEmpty(selectInfo.str) ? "空" : selectInfo.str;

                    if (richText)
                    {
                        return string.Format("{0}<color=grey>({1}:{2})</color>", str, LocalizationManager.Language, str1);
                    }
                    else {
                        return string.Format("{0}({1}:{2})", str, LocalizationManager.Language, str1);
                    }

                    
                }
                else {
                    return string.IsNullOrEmpty(languageInfo.str) ? "空" : languageInfo.str;
                } 
            }
              
        }


        // 创建
        private void CreateLanguageInfo(MultiLanguageType type)
        { 
            int id = GenerateID();
             
            // 给所有的语言添加数据
            foreach (var item in multiLanguageConfigs.Languages)
            { 
                LanguageInfo info = new LanguageInfo();
                info.id = id;
                info.type = type;
                item.languagesInfo.Add(info);
                item.ClearCache();
                item.Save();
            }


            AssetDatabase.SaveAssets();

            this.Reload();

            EditorApplication.delayCall += () => {
                this.SetSelection(new int[] { id });
                this.FrameItem(id);
            }; 
        }

        // 生成id
        private int GenerateID()
        {
            string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(MultiLanguageConfigs).FullName));

            List<MultiLanguageConfigs> configs = new List<MultiLanguageConfigs>();

            foreach (var guid in guids)
            {
                string asset_path = AssetDatabase.GUIDToAssetPath(guid);
                MultiLanguageConfigs config = AssetDatabase.LoadAssetAtPath<MultiLanguageConfigs>(asset_path);
                if (config == null) continue;
                configs.Add(config);
            }

            int id = 0;

            foreach (var item in configs)
            {
                if (item.Languages == null || item.Languages.Count == 0) continue;

                foreach (LanguageInfo languageInfo in item.Languages[0].languagesInfo)
                {
                    if (languageInfo.id > id)
                        id = languageInfo.id;
                }
            }
             
            return ++id;
        }

        // 删除
        private void Delete(int id)
        {
            // 删除所有语言的配置
            foreach (var item in multiLanguageConfigs.Languages)
            { 
                item.ClearCache();

                LanguageInfo info = item.GetLanguageInfo(id); 
                item.languagesInfo.Remove(info); 
                
                item.Save();
                item.ClearCache();
            }

            AssetDatabase.SaveAssets();
          
        }
         
        private void ShowMenu(GenericMenu menu)
        {

            menu.AddItem(new GUIContent("创建/String"), false, () => { CreateLanguageInfo(MultiLanguageType.String); });
            menu.AddItem(new GUIContent("创建/Image"), false, () => { CreateLanguageInfo(MultiLanguageType.Image); });
            menu.AddItem(new GUIContent("创建/NetworkImage"), false, () => { CreateLanguageInfo(MultiLanguageType.NetworkImage); });
             
            menu.ShowAsContext();
        }

    }



    [CustomEditor(typeof(LanguageConfig))]
    public class LanguageConfigsInspector : Editor
    {

        private static LanguageConfigsInspector _instance;
        public static LanguageConfigsInspector Instance
        {
            get
            {
                if (_instance == null)
                    _instance = CreateInstance<LanguageConfigsInspector>();
                return _instance;
            }
        }


        private LanguageConfig currentLanguageConfig;
        private SerializedObject currentSerializedObject;
        private List<SerializedProperty> properties = new List<SerializedProperty>();
          
        private LanguageInfoListTree languageInfoListTree = null;
          
        private MultiColumnHeaderState multiColumnHeaderState = null;
          
        private MultiLanguageConfigs currentMultiLanguageConfig = null;
         
         
        public override void OnInspectorGUI()
        {
            EditorGUI.BeginDisabledGroup(true);
            base.OnInspectorGUI();
            EditorGUI.EndDisabledGroup();
        }

        // 这个不需要自定义属性(因为这个里面的内容是固定的)
        public void OnInspectorGUI(LanguageConfig data, LocalizationConfigsWindow window, MultiLanguageConfigs currentMultiLanguageConfig)
        { 
            if (data == null) 
            {
                return;
            }

            if (currentLanguageConfig != data || this.currentMultiLanguageConfig != currentMultiLanguageConfig)
            {
                currentSerializedObject = null; 
                languageInfoListTree = null;

                currentLanguageConfig = data; 
                this.currentMultiLanguageConfig = currentMultiLanguageConfig;
            }


            if ( currentSerializedObject == null)
            {
                currentSerializedObject = new SerializedObject(data);
                properties = currentSerializedObject.GetAllSerializedProperty(); 
            }

            if (properties == null) return;

            currentSerializedObject.Update();

            foreach (SerializedProperty property in properties)
            {
                if (property.name == "language")
                {
                    EditorGUI.BeginDisabledGroup(true);
                    EditorGUILayout.PropertyField(property);
                    EditorGUI.EndDisabledGroup();
                }
                else if (property.name == "displayName")
                {
                    OnDisplayNameGUI(property, window);
                }
                else if (property.name == "languagesInfo")
                {
                    OnLanguageInfoGUI(property, window);
                }
                else
                {
                    EditorGUILayout.PropertyField(property);
                }
            }

            GUILayout.FlexibleSpace();

            GUILayout.BeginHorizontal();

            GUILayout.FlexibleSpace();

            EditorGUI.BeginDisabledGroup(currentMultiLanguageConfig.Languages.Count <= 1);

            if (GUILayout.Button("一键翻译"))
            { 
                EditorWindow.GetWindow<TranslateOptionWindow>().ShowOption(currentMultiLanguageConfig, data.language); 
            }

            EditorGUI.EndDisabledGroup();

            EditorGUI.BeginDisabledGroup(data.language == LocalizationManager.Language);
             
           

            if (GUILayout.Button(data.language == LocalizationManager.Language ? "已选择" : "选择"))
                LocalizationManager.Language = data.language;

            EditorGUI.EndDisabledGroup();

            GUILayout.Space(10);
            GUILayout.EndHorizontal();

            currentSerializedObject.ApplyModifiedProperties();
        }

        private void OnDisplayNameGUI(SerializedProperty property, LocalizationConfigsWindow window)
        {
            EditorGUILayout.LabelField(string.Empty, "显示名称", "BoldLabel");
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.DelayedTextField(property);
            if (EditorGUI.EndChangeCheck())
            {
                currentSerializedObject.ApplyModifiedProperties();
                window.languageListTree.Reload();
            }
        }


        private void OnLanguageInfoGUI(SerializedProperty property, LocalizationConfigsWindow window)
        { 
            EditorGUILayout.LabelField(string.Empty, "语言配置", "BoldLabel");

            //if (reorderableList == null)
            //{
            //    reorderableList = new ReorderableList(currentSerializedObject, property);
            //    reorderableList.headerHeight = 1;
            //    reorderableList.drawElementCallback += ElementCallbackDelegate;
            //    reorderableList.onAddCallback += AddCallbackDelegate;
            //    reorderableList.onRemoveCallback += RemoveCallbackDelegate; 
            //}
             

            if (languageInfoListTree == null) 
            {

                if (multiColumnHeaderState == null)
                { 
                    var headerState = LanguageInfoListTree.CreateDefaultMultiColumnHeaderState();
                    if (MultiColumnHeaderState.CanOverwriteSerializedFields(multiColumnHeaderState, headerState))
                        MultiColumnHeaderState.OverwriteSerializedFields(multiColumnHeaderState, headerState);
                    multiColumnHeaderState = headerState;
                }


                languageInfoListTree = new LanguageInfoListTree(window.languageInfoState, multiColumnHeaderState, currentLanguageConfig,currentMultiLanguageConfig);

                languageInfoListTree.Reload();
            }

            EditorGUI.BeginChangeCheck();

            languageInfoListTree.searchString = EditorGUILayout.TextField(string.Empty, languageInfoListTree.searchString, "SearchTextField", GUILayout.MinWidth(0));

            if (EditorGUI.EndChangeCheck())
            {
                if (string.IsNullOrEmpty(languageInfoListTree.searchString) && languageInfoListTree.state.selectedIDs.Count > 0)
                {
                    EditorApplication.delayCall += () =>
                    {
                        languageInfoListTree.FrameItem(languageInfoListTree.state.selectedIDs[0]);
                    };
                }
            }

            GUILayout.Space(-2); 
              
            Rect rect = GUILayoutUtility.GetRect(0, 10);
             
            rect.height = window.position.height - rect.y - 25;

            rect.x += 3;
            rect.width -= 6;
            languageInfoListTree.OnGUI(rect); 
        }
         
        
        internal static Texture2D GetImage(string projectName, string assetName)
        {

            if (string.IsNullOrEmpty(projectName) || string.IsNullOrEmpty(assetName))
                return null;

            XFABProject project = XFABProjectManager.Instance.GetProject(projectName);

            if (project != null)
            {
                List<XFABAssetBundle> bundles = project.GetAllAssetBundles();

                foreach (var bundle in bundles)
                {
                    if (bundle == null)
                    {
                        continue;
                    }
                    string asset_path = bundle.GetAssetPathByFileName(assetName, typeof(Texture2D));

                    if (string.IsNullOrEmpty(asset_path))
                        asset_path = bundle.GetAssetPathByFileName(assetName, typeof(Sprite));

                    if (string.IsNullOrEmpty(asset_path))
                        continue;
                    Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(asset_path);
                    if (texture != null)
                        return texture;
                }
            }

            return null;
        }

    }
}


